package org.ktx.osr.service

import android.app.Activity
import android.app.Service
import android.content.Context
import android.content.Intent
import android.media.projection.MediaProjection
import android.media.projection.MediaProjectionManager
import android.os.Handler
import android.os.IBinder
import android.os.Looper
import android.util.Log
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.Job
import kotlinx.coroutines.MainScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import org.ktx.osr.PermissionActivity
import org.ktx.osr.data.SettingsRepository
import org.ktx.osr.data.UploadConfig
import org.ktx.osr.ui.AppSettings
import java.io.File
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
import kotlin.properties.Delegates

/**
 * 屏幕录制服务
 * 负责协调各个组件完成屏幕录制功能
 * 功能边界：服务生命周期管理、组件协调、不处理具体的录制逻辑
 */
class ScreenRecordingService : Service() {
    private var mediaProjectionManager: MediaProjectionManager? = null
    private var mediaProjection: MediaProjection? = null
    private var recordingSession: RecordingSession? = null
    private var notificationManager: RecordingNotificationManager? = null
    private var floatingWidgetManager: FloatingWidgetManager? = null
    private var settingsRepository: SettingsRepository? = null
    private var currentSettings: AppSettings? = null
    
    private var pauseWaiter: CompletableDeferred<Unit>? = null
    private var recordingState: Int by Delegates.observable(STATE_STOPPED) { _, oldValue, newValue ->
        if (oldValue == newValue) return@observable
        
        // 更新外部状态流
        recordingStateFlow.value = newValue
        
        // 更新浮动控件状态
        floatingWidgetManager?.updateRecordingState(newValue)
        
        // 管理录制时长更新器
        when (newValue) {
            STATE_RECORDING -> {
                if (pauseWaiter?.isActive == true) {
                    pauseWaiter?.complete(Unit)
                } else {
                    startRecordingDurationUpdater()
                }
            }
            STATE_STOPPED -> stopRecordingDurationUpdater()
            STATE_PAUSED -> {
                pauseWaiter = CompletableDeferred()
            }
        }
        
        // 处理暂停状态变化
        if (oldValue == STATE_PAUSED) {
            pauseWaiter?.complete(Unit)
            pauseWaiter = null
        }
    }
    
    private var durationUpdater: Job? = null
    private val mainScope = MainScope()

    companion object {
        const val ACTION_START_RECORDING = "org.ktx.osr.action.START_RECORDING"
        const val ACTION_STOP_RECORDING = "org.ktx.osr.action.STOP_RECORDING"
        const val ACTION_SHOW_FLOATING_WIDGET = "org.ktx.osr.action.SHOW_FLOATING_WIDGET"
        const val ACTION_HIDE_FLOATING_WIDGET = "org.ktx.osr.action.HIDE_FLOATING_WIDGET"
        const val EXTRA_RESULT_CODE = "resultCode"
        const val EXTRA_DATA = "data"

        const val STATE_STOPPED = 0
        const val STATE_RECORDING = 1
        const val STATE_PAUSED = 2

        val recordingStateFlow = MutableStateFlow(STATE_STOPPED)

        /**
         * 显示浮动控件
         */
        fun showFloatingWidget(context: Context) {
            val intent = Intent(context, ScreenRecordingService::class.java).apply {
                action = ACTION_SHOW_FLOATING_WIDGET
            }
            context.startService(intent)
        }

        /**
         * 隐藏浮动控件
         */
        fun hideFloatingWidget(context: Context) {
            val intent = Intent(context, ScreenRecordingService::class.java).apply {
                action = ACTION_HIDE_FLOATING_WIDGET
            }
            context.startService(intent)
        }

        /**
         * 停止录制
         */
        fun stopRecording(context: Context) {
            val intent = Intent(context, ScreenRecordingService::class.java).apply {
                action = ACTION_STOP_RECORDING
            }
            context.startService(intent)
        }

        /**
         * 请求开始录制（通过PermissionActivity处理权限）
         */
        fun requestStartRecording(context: Context) {
            PermissionActivity.startForAction(
                context,
                PermissionActivity.ACTION_START_RECORDING
            )
        }

        /**
         * 请求显示浮动控件（通过PermissionActivity处理）
         */
        fun requestShowFloatingWidget(context: Context) {
            PermissionActivity.startForAction(
                context, 
                PermissionActivity.ACTION_SHOW_FLOATING_WIDGET
            )
        }

        /**
         * 请求隐藏浮动控件（通过PermissionActivity处理）
         */
        fun requestHideFloatingWidget(context: Context) {
            PermissionActivity.startForAction(
                context, 
                PermissionActivity.ACTION_HIDE_FLOATING_WIDGET
            )
        }
    }


    override fun onBind(intent: Intent): IBinder? {
        return null
    }

    override fun onCreate() {
        super.onCreate()
        
        // 初始化管理器
        mediaProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        notificationManager = RecordingNotificationManager(this)
        floatingWidgetManager = FloatingWidgetManager(this)
        settingsRepository = SettingsRepository(this)
    }

    /**
     * 显示浮动控件
     */
    private fun showFloatingWidget() {
        floatingWidgetManager?.showWidget(
            onToggleRecording = {
                when (recordingState) {
                    STATE_PAUSED -> resumeRecording()
                    STATE_RECORDING -> pauseRecording()
                    else -> { startRecording() }
                }
            },
            onStopRecording = {
                if (recordingState != STATE_STOPPED) {
                    stopRecording()
                }
            }
        )
    }

    /**
     * 隐藏浮动控件
     */
    private fun hideFloatingWidget() {
        floatingWidgetManager?.hideWidget()
    }

    /**
     * 开始录制时长更新器
     */
    private fun startRecordingDurationUpdater() {
        durationUpdater?.cancel()
        durationUpdater = mainScope.launch {
            var seconds = 0
            while (recordingState == STATE_RECORDING || recordingState == STATE_PAUSED) {
                pauseWaiter?.await()
                val mins = seconds / 60
                val secs = seconds % 60
                val durationText = String.format(Locale.getDefault(), "%02d:%02d", mins, secs)
                floatingWidgetManager?.setRecordingDuration(durationText)
                delay(1000)
                seconds++
            }
        }
    }

    /**
     * 停止录制时长更新器
     */
    private fun stopRecordingDurationUpdater() {
        pauseWaiter?.cancel()
        durationUpdater?.cancel()
    }

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        when (intent?.action) {
            ACTION_START_RECORDING -> {
                val resultCode = intent.getIntExtra(EXTRA_RESULT_CODE, Activity.RESULT_CANCELED)
                val data: Intent? = intent.getParcelableExtra(EXTRA_DATA)
                if (resultCode == Activity.RESULT_OK && data != null) {
                    startForeground(123, notificationManager?.createForegroundNotification())
                    startRecording(resultCode, data)
                }
            }

            ACTION_STOP_RECORDING -> {
                stopRecording()
            }
            
            ACTION_SHOW_FLOATING_WIDGET -> {
                showFloatingWidget()
            }
            
            ACTION_HIDE_FLOATING_WIDGET -> {
                hideFloatingWidget()
            }
        }
        return START_NOT_STICKY
    }

    /**
     * 开始录制
     */
    private fun startRecording(resultCode: Int, data: Intent) {
        if (recordingState != STATE_STOPPED) return

        mediaProjection = mediaProjectionManager?.getMediaProjection(resultCode, data)
        if (mediaProjection == null) {
            return
        }

        // 注册MediaProjection回调
        mediaProjection?.registerCallback(object : MediaProjection.Callback() {
            override fun onStop() {
                super.onStop()
                stopRecording()
            }
        }, Handler(Looper.getMainLooper()))

        // 加载设置并开始录制
        mainScope.launch {
            currentSettings = settingsRepository?.getCurrentSettings()
            val settings = currentSettings ?: AppSettings()

            // 创建录制会话
            recordingSession = RecordingSession(this@ScreenRecordingService, settings, mediaProjection!!)
            
            if (recordingSession?.startSession() == true) {
                recordingState = STATE_RECORDING
            } else {
                releaseMediaProjection()
            }
        }
    }

    /**
     * 开始录制
     */
    /**
     * 直接开始录制（假设已经有mediaProjection）
     */
    private fun startRecording() {
        if (recordingState != STATE_STOPPED) return

        // 加载设置并开始录制
        PermissionActivity.startForAction(this, PermissionActivity.ACTION_START_RECORDING)
    }

    /**
     * 暂停录制
     */
    private fun pauseRecording() {
        if (recordingState != STATE_RECORDING) return
        recordingSession?.pauseRecording()
        recordingState = STATE_PAUSED
    }

    /**
     * 恢复录制
     */
    private fun resumeRecording() {
        if (recordingState != STATE_PAUSED) return
        recordingSession?.resumeRecording()
        recordingState = STATE_RECORDING
    }

    /**
     * 停止录制
     */
    private fun stopRecording() {
        if (recordingState == STATE_STOPPED && mediaProjection == null) {
            return
        }

        recordingState = STATE_STOPPED

        // 停止录制会话
        recordingSession?.stopSession()

        // 提交音视频处理任务
        submitMediaProcessingTask()

        // 释放资源
        releaseMediaProjection()
        recordingSession = null

        stopForeground(STOP_FOREGROUND_REMOVE)
    }

    /**
     * 提交音视频处理任务
     */
    private fun submitMediaProcessingTask() {
        val settings = currentSettings ?: AppSettings()
        val videoFile = recordingSession?.getVideoFile()
        val audioFile = recordingSession?.getAudioFile()

        if (videoFile == null || !videoFile.exists()) {
            Log.e("ScreenRecording", "Video file:${videoFile} not found for processing")
            return
        }

        // 创建最终输出文件
        val finalOutputFile = getFinalVideoFilePath()
        if (finalOutputFile == null) {
            Log.e("ScreenRecording", "Failed to create final output file:${finalOutputFile}")
            return
        }

        try {
            // 创建上传配置
            val uploadConfig = createUploadConfig(settings)

            // 提交任务到MediaProcessingService
            val intent = Intent(this, MediaProcessingService::class.java).apply {
                action = MediaProcessingService.ACTION_SUBMIT_TASK
                putExtra(MediaProcessingService.EXTRA_VIDEO_FILE, videoFile.absolutePath)
                putExtra(MediaProcessingService.EXTRA_OUTPUT_FILE, finalOutputFile.absolutePath)

                // 如果有音频文件且需要处理音频，则添加音频文件路径
                if (audioFile != null && audioFile.exists() && (settings.includeSystemSound || settings.includeMicrophone)) {
                    putExtra(MediaProcessingService.EXTRA_AUDIO_FILE, audioFile.absolutePath)
                }

                // 添加上传配置
                if (uploadConfig != null) {
                    putExtra(MediaProcessingService.EXTRA_UPLOAD_CONFIG, uploadConfig)
                }
            }

            startService(intent)
            Log.d("ScreenRecording", "Media processing task submitted")

        } catch (e: Exception) {
            Log.e("ScreenRecording", "Error submitting media processing task", e)
        }
    }


    /**
     * 创建上传配置
     * 这里可以根据应用设置或用户配置来创建上传配置
     */
    private fun createUploadConfig(settings: AppSettings): UploadConfig? {
        // 这里可以根据实际需求来配置上传参数
        // 例如从设置中读取服务器地址、API密钥等
        // 暂时返回null，表示不上传
        return null

        // 示例配置：
        // return UploadConfig(
        //     serverUrl = "https://your-server.com/upload",
        //     apiKey = "your-api-key",
        //     uploadOriginalFiles = true,
        //     uploadProcessedFiles = true
        // )
    }

    private fun getFinalVideoFilePath(): File? {
        val settings = currentSettings ?: AppSettings()
        val directory = getRecordingDirectory(settings)

        if (!directory.exists()) {
            if (!directory.mkdirs()) {
                Log.e("ScreenRecording", "Failed to create output directory")
                return null
            }
        }

        val timestamp = SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(Date())
        val extension = when (settings.videoFormat.uppercase()) {
            "MP4" -> "mp4"
            "WEBM" -> "webm"
            else -> "mp4"
        }
        return File(directory, "merged_$timestamp.$extension")
    }

    /**
     * 获取录制目录
     */
    private fun getRecordingDirectory(settings: AppSettings): File {
        return when (settings.saveLocation) {
            "SD Card" -> {
                try {
                    val publicDir = File(
                        android.os.Environment.getExternalStoragePublicDirectory(android.os.Environment.DIRECTORY_MOVIES),
                        "ScreenRecordings"
                    )
                    if (publicDir.exists() || publicDir.mkdirs()) {
                        val testFile = File(publicDir, "test_write.tmp")
                        if (testFile.createNewFile()) {
                            testFile.delete()
                            return publicDir
                        }
                    }
                } catch (e: Exception) {
                    Log.w("ScreenRecording", "Cannot write to public directory, using app-specific directory", e)
                }
                File(getExternalFilesDir(android.os.Environment.DIRECTORY_MOVIES), "ScreenRecordings")
            }
            else -> {
                File(getExternalFilesDir(android.os.Environment.DIRECTORY_MOVIES), "ScreenRecordings")
            }
        }
    }

    /**
     * 释放MediaProjection资源
     */
    private fun releaseMediaProjection() {
        try {
            mediaProjection?.stop()
        } catch (e: Exception) {
            e.printStackTrace()
        }
        mediaProjection = null
    }

    override fun onDestroy() {
        super.onDestroy()
        
        if (recordingState != STATE_STOPPED || mediaProjection != null) {
            stopRecording()
        }

        // 隐藏浮动控件
        floatingWidgetManager?.hideWidget()
        
        // 释放资源
        releaseMediaProjection()
        recordingSession = null
        currentSettings = null
    }
}
